﻿using Yxinmt.Interface;
using Yxinmt.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Yxinmt.Components
{
    public class BaseComponent : IComponent
    {
        public Guid Id { get; set; }
        public String Name { get; set; }
        public IWindow Window { get; set; }

        public virtual bool GetVisible()
        {
            return false;
        }

        public List<IComponent> ComponentList { get; set; }
        public List<IControl> ControlList { get; set; }
        protected List<IControl> _ColumnControlList { get; set; }
        protected Dictionary<string, object> _Property { get; set; }
        protected List<Dictionary<string, object>> _PropertyList { get; set; }

        /// <summary>
        /// 获取控件列表
        /// </summary>
        /// <returns></returns>
        public List<System.Windows.FrameworkElement> GetElements()
        {
            return this.ControlList.Select(s => s.Element).ToList();
        }

        protected void InitSet()
        {
            Id = _Property.ContainsKey("id") ? _Property.GetValue<Guid>("id") : Guid.NewGuid();
            Name = _Property.GetStringValue("name");
            Window.ComponentList.Add(this);
        }

        /// <summary>
        /// 事件加载
        /// </summary>
        public virtual void EventLoad()
        {
            this.ControlList.ForEach(c => c.EventLoad());
            if (ComponentList != null) this.ComponentList.ForEach(c => c.EventLoad());
            if (_ColumnControlList != null) this._ColumnControlList.ForEach(c => c.EventLoad());
        }

        /// <summary>
        /// 数据加载
        /// </summary>
        public virtual void DataLoad()
        {
            this.ControlList.ForEach(c => c.DataLoad());
            if (ComponentList != null) this.ComponentList.ForEach(c => c.DataLoad());
            if (_ColumnControlList != null) this._ColumnControlList.ForEach(c => c.DataLoad());
        }

        protected void SetPropertyKvp(List<string> keyList, Dictionary<string, object> property)
        {
            keyList.ForEach(key => { if (_Property.ContainsKey(key) && !property.ContainsKey(key)) property[key] = _Property[key]; });
        }

        public virtual object GetValue()
        {
            return null;
        }

        public virtual void SetValue(object value)
        {
        }

        public bool IsEdit()
        {
            return _Property.GetValue<bool>("IsEdit");
        }

        public virtual bool ValidateNullable(out string message)
        {
            message = string.Empty;
            return true;
        }

        protected void GetViewPropertyList()
        {
            this._PropertyList = this._Property.GetValue<List<Dictionary<string, object>>>("properties");
        }

        protected void SetView()
        {
            GetViewPropertyList();
            this.SetPropertyList();
        }

        protected void SetPropertyList()
        {
            if (_PropertyList == null || ComponentList == null) return;

            _PropertyList.ForEach(p =>
            {
                this.Window.InitComponent(p, ComponentList);
            });
        }

        /// <summary>
        /// 获取控件列表
        /// </summary>
        /// <returns></returns>
        protected List<System.Windows.FrameworkElement> GetComponentsElements()
        {
            return (from a in this.ComponentList
                    from b in a.GetElements()
                    select b).ToList();
        }

        public List<IControl> GetComponentsControls()
        {
            return (from a in this.ComponentList
                    from b in a.ControlList
                    select b).ToList();
        }

        public object GetComponentsValue()
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();

            if (ComponentList != null) ComponentList.ForEach(c => dict.Add(c.Name, c.GetValue()));

            return dict;
        }

        public void SetComponentsValue(object value)
        {
            if (ComponentList == null) return;

            if (value is Dictionary<string, object>)
            {
                Dictionary<string, object> dict = value as Dictionary<string, object>;
                ComponentList.ForEach(c => { if (dict.ContainsKey(c.Name)) c.SetValue(dict[c.Name]); });
            }
            else if (value != null)
            {
                List<PropertyInfo> propertyList = value.GetType().GetProperties().ToList();
                PropertyInfo p = null;

                ComponentList.ForEach(c =>
                {
                    p = propertyList.Where(w => w.Name.Equals(c.Name)).FirstOrDefault();
                    if (p != null) c.SetValue(p.GetValue(value));
                });
            }
        }

        public virtual void SetVisible(bool visible)
        {
            if (ComponentList != null) ComponentList.ForEach(c => c.SetVisible(visible));

            if (ControlList != null) ControlList.ForEach(c => c.SetVisible(visible));
        }

        protected void SetPropertyValue(Dictionary<string, object> property, string name, string targetName)
        {
            if (_Property.ContainsKey(targetName)) property[name] = _Property[targetName];
        }

        protected void SetDefaultPropertyValue(Dictionary<string, object> property, string name, object value)
        {
            if (!property.ContainsKey(name)) property[name] = value;
        }

        protected virtual void SetReceiveData(object data, int actionType)
        {
        }

        protected void AddControl<T>(List<T> list) where T : IComponent
        {
            T ctl = list.Where(w => w.Name == Name).FirstOrDefault();
            if (ctl != null) list.Remove(ctl);

            list.Add((T)((IComponent)this));
        }

        protected IComponent AddProperty(Dictionary<string, object> property)
        {
            this._PropertyList = this._PropertyList ?? new List<Dictionary<string, object>>();
            this._PropertyList.Add(property);
            this.Window.InitComponent(property, ComponentList);
            return ComponentList.LastOrDefault();
        }

        public virtual void SetBackColor(string color)
        {

        }

        public virtual IComponent Add(Dictionary<string, object> property)
        {
            return null;
        }

        public virtual void Remove(Dictionary<string, object> property)
        {
        }
    }
}
